package com.pcitc.paas.feign.demo.consumer.server.config;

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.form.ContentType;
import feign.form.FormEncoder;
import feign.form.MultipartFormContentProcessor;
import feign.form.spring.SpringManyMultipartFilesWriter;
import feign.form.spring.SpringSingleMultipartFileWriter;
import org.springframework.web.multipart.MultipartFile;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * description: <br>
 * createTime: 2021/6/21 17:59 <br>
 *
 * @author zzh
 */
public class NewFeignSpringFormEncoder extends FormEncoder {
    public NewFeignSpringFormEncoder() {
        this(new Encoder.Default());
    }

    public NewFeignSpringFormEncoder(Encoder delegate) {
        super(delegate);
        MultipartFormContentProcessor processor = (MultipartFormContentProcessor)this.getContentProcessor(ContentType.MULTIPART);
        processor.addWriter(new SpringSingleMultipartFileWriter());
        processor.addWriter(new SpringManyMultipartFilesWriter());
    }

    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
        if (object instanceof Map || bodyType instanceof ParameterizedTypeImpl && ((ParameterizedTypeImpl)bodyType).getRawType().equals(Map.class)) {
            Map<String, Object> data = (Map)object;
            Set<String> nullSet = new HashSet();
            Iterator var6 = data.entrySet().iterator();

            while(var6.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry)var6.next();
                Object value = entry.getValue();
                if (value instanceof MultipartFile) {
                    MultipartFile file = (MultipartFile)value;
                    super.encode(Collections.singletonMap(file.getName(), value), MAP_STRING_WILDCARD, template);
                    return;
                }

                if (value instanceof MultipartFile[]) {
                    MultipartFile[] file = (MultipartFile[])((MultipartFile[])value);
                    if (file != null) {
                        super.encode(Collections.singletonMap(file.length == 0 ? "" : file[0].getName(), value), MAP_STRING_WILDCARD, template);
                        return;
                    }
                }

                if (value == null) {
                    nullSet.add(entry.getKey());
                }
            }

            var6 = nullSet.iterator();

            while(var6.hasNext()) {
                String s = (String)var6.next();
                data.remove(s);
            }

            super.encode(data, MAP_STRING_WILDCARD, template);
        } else {
            super.encode(object, bodyType, template);
        }
    }
}
